/***************************************************************************//**
 * @file mac_receiver.c
 * @brief for mac 
 * @author ze .
 * @date  2022/7/03.
 * @copyright Copyright 
 ******************************************************************************/

#include "mac_receiver.h"
#include "mac_packetHandle.h"
#include "mac_transmitter.h"
#include "mac_TDMA.h"
#include "mac_fhss.h"
#include "mac_timeSync.h"
#include "softwareMultiTimer.h"
#include "em_core.h"
#include "device_type.h"

//#define CHECK_RF_RX_IDLE (EN_MAC_RF_STATE_IDLE == getRfState() || EN_MAC_RF_STATE_WAIT_PREAMBLE == getRfState()) //ToDo 可直接读取芯片状态，IO脚/寄存器，为快速反应，半双工芯片 RX IDLE 表示可重新开启接收

#define CHECK_RECV_EVENT_TYPE_IS_RX_WINDOW(a) (a == EN_RECV_REQ_LISTEN_BACKRSSI_WINDOW || a == EN_RECV_REQ_ACK_WINDOW || a == EN_RECV_REQ_SYNC_RXWAKE_WINDOW)
#define RECV_EVENT_RX_WINDOW_BITMASK          ( (uint32_t)(GET_DW_BIT_MASK(EN_RECV_REQ_LISTEN_BACKRSSI_WINDOW) | GET_DW_BIT_MASK(EN_RECV_REQ_ACK_WINDOW) | GET_DW_BIT_MASK(EN_RECV_REQ_SYNC_RXWAKE_WINDOW)) )
#define RECV_EVENT_RX_ALWAYS_ON_BITMASK     (~RECV_EVENT_RX_WINDOW_BITMASK)

#define MAC_RX_STATEMACHINE_HARD_TIMER  EN_LP_HARD_TIMER_EM3_SYS_RTC //receiver 和 transmitter 均使用sysRtc， RTC_1给APP应用使用

typedef struct 
{   
    uint8_t   isFastHopOn;  //若Hop相关值发生改变，则需进入事件处理,ToDo 该flag直接从寄存器获取
    uint8_t   byCurrentRxChan; //当前的接收信道，若HopOn 则表示 mainCH，若Hopoff 则表示常收信道
    RECV_REQ_E enHandlingEventType;//状态机正在处理的事件类型
    PFUNC_RX_CALLBACK pMacCallbackRx;
    //PFUNC_RX_CALLBACK ppMacCallbackRx[EN_RX_STATE_MAX];//在发送的各个状态回调
}RX_STATE_CTRL_BLOCK_ST;


//变量声明和定义
static RX_STATE_CTRL_BLOCK_ST s_stRxCtrlBlock;
static STATEM_STATE_MACHINE_ST s_instRxStateMachine;

static volatile uint32_t s_dwRecvEventBitMask = 0;
static volatile uint8_t s_pbyRecvEventMainChan[EN_RX_STATE_MAX];//通信信道
static volatile uint32_t  s_dwMacRxEventTypeBitMask = 0;
static volatile uint32_t  s_dwMacRxEventValueBitMask = 0;

MultiTimer waitPreambleWindowTimer ={.Handle = 0x0100}; //USE SYSRTC1 ,256,不同的事件，其等待有效前导码的计时不同
MultiTimer waitPayloadTimer ={.Handle = 0x0101}; //USE SYSRTC1 ,

static int8_t s_currentBackRssi = RAIL_RSSI_INVALID_DBM;
//暂时屏蔽掉 对各个信道的背景噪声数据的存储，节省RAM
//static int8_t s_chanBackRssi[RF_CHAN_NUM_MAX] ={0x00,};//仅在400ms 切换主信道时更新

int8_t getCurrentBackRssi(void)
{
  return s_currentBackRssi;
}

//函数声明和定义
//ToDo 若当前RF芯片处于TX态如何处理？
void startRx(uint8_t chan, uint8_t isFastHOn)
{
  static int8_t mainChRssi = RAIL_RSSI_INVALID_DBM;
  static int8_t resyncChRssi = RAIL_RSSI_INVALID_DBM ;
  static uint8_t isRest = 1;
  uint8_t temp8;
  uint8_t ret = 0xFF;
  uint8_t ret2 = 0xFF;
  uint8_t isHopReConfged = 0;

  if(EN_MAC_RF_STATE_TX_PAYLOADING == getRfState()) //ToDo 统一到startRx接口
  {
      //printf("#");
      return ;
  }

  if(isRest || (isFastHOn && chan != bsp_rf_get_hop_main_chan()))////ToDo 统一到startRx接口，重启初次需配置，每400ms重新切换频段前，读取上次信号强度值; 系统切换频段前后有+-10ms的GAP区域
  {
#ifdef BACK_RSSI_RANDOM_CHAN_GET
      mainChRssi = (bsp_rf_get_raw_rssi(false) >> 2);
      resyncChRssi = mainChRssi;
#else
      int8_t tempi8 = RAIL_RSSI_INVALID_DBM;
      if(bsp_rf_get_hop_resync_chan() == bsp_rf_get_hop_main_chan())
      {
          tempi8 = (bsp_rf_get_raw_rssi(false) >> 2); //此处阻塞运行，可能导致看门狗复位，需改造！超时2ms退出 ——> 240229 已改成不阻塞，可能返回值为RAIL_RSSI_INVALID_DBM
          if(get_mac_printf_log())
            printf("aR%d,",tempi8);
          if(tempi8 > RAIL_RSSI_INVALID_DBM)
          {
            mainChRssi = tempi8 ;
            resyncChRssi =tempi8 ;
          }
      }
      else
      {
          tempi8 = (bsp_rf_get_hop_main_chan_rssi() >> 2);//当前主信道，背景信号强度
          if(get_mac_printf_log())
            printf("mR%d,",tempi8);
          if(tempi8 > RAIL_RSSI_INVALID_DBM){
            mainChRssi = tempi8;}

          tempi8 = (bsp_rf_get_hop_resync_chan_rssi() >> 2);//当前备用信道，背景信号强度
          if(get_mac_printf_log())
            printf("rR%d,",tempi8);
          if(tempi8 > RAIL_RSSI_INVALID_DBM){
            resyncChRssi = tempi8;}
      }
#endif
      if(mainChRssi > RAIL_RSSI_INVALID_DBM)
      {
          s_currentBackRssi = (mainChRssi >> 1) + (resyncChRssi >> 1) ; //主信道和备用信道取平均

          temp8 = bsp_rf_get_hop_main_chan();
          //暂时屏蔽掉 对各个信道的背景噪声数据的存储，节省RAM
//          if(temp8 < RF_CHAN_NUM_MAX)
//          {
//            s_chanBackRssi[temp8] = s_currentBackRssi;//更新 具体信道的信号亮度值，后续换至其他地方，取平均？
//          }
      }

      ret = bsp_rf_set_hop_main_chan(chan);
      if(ret == 0)
      {
        s_stRxCtrlBlock.byCurrentRxChan = chan;
        if(!isRest)
          isHopReConfged = 1;//考虑到SLEEP DEVICE 也使用同一套MAC层，PHY驱动，此处不调用enable
      }

      isRest = 0;
      if(get_mac_printf_log())
        printf("CH%d-%d,cR%d",chan,ret,s_currentBackRssi);
  }
  else
  {
      s_stRxCtrlBlock.byCurrentRxChan = chan;
  }

  //ToDo  调用mac_fhss.h内的函数，使能AutoHop，调用hopping函数时，是否先进入Idle状态？
  if(isFastHOn != s_stRxCtrlBlock.isFastHopOn || isHopReConfged)
  {
      if(isFastHOn)
      {
          ret2 = bsp_rf_rx_channel_hopping_enable(true,false);
      }
      else
      {
          ret2 = bsp_rf_rx_channel_hopping_enable(false,false);
      }
      s_stRxCtrlBlock.isFastHopOn = isFastHOn;
  }
  if(bsp_rf_antenna_diversity_feature_get())
  {
      bsp_rf_config_rx_option(RAIL_RX_OPTION_ANTENNA_AUTO,RAIL_RX_OPTION_ANTENNA_AUTO); //开启天线自动切换接收
//      bsp_rf_config_rx_option(RAIL_RX_OPTION_ANTENNA0,RAIL_RX_OPTION_ANTENNA1); //开启天线1接收,若不配置，默认为Ant0，硬件标识可匹配
  }
  ret = bsp_rf_start_rx(chan,NULL);
  if(get_mac_printf_log())
    printf("RA %d,%d,%d-%d\r\n",ret,chan,isFastHOn,ret2);
}

void clearHopOnflag(void)
{
  s_stRxCtrlBlock.isFastHopOn = false;
}

static void setRecvReqEventType(RECV_REQ_E type)
{
    CORE_DECLARE_IRQ_STATE;
    CORE_ENTER_CRITICAL();     
    s_dwRecvEventBitMask |= GET_DW_BIT_MASK(type);  
    CORE_EXIT_CRITICAL();        
}

// 清除事件
static void clearRecvReqEventType(RECV_REQ_E type)
{
    CORE_DECLARE_IRQ_STATE;
    CORE_ENTER_CRITICAL();      
    s_dwRecvEventBitMask &= ~(GET_DW_BIT_MASK(type));
    CORE_EXIT_CRITICAL();     
}

#ifdef SLEEP_DEVICE
//仅对SLEEP DEVICE 宏设备有效
void rxAlwaysOnEnable(bool isEnable)
{
  if(isEnable)
  {
    setMacRecvEvent(EN_RECV_REQ_ALWAYS_ON_CHAN,getAccessChan(CHAN_TYPE_MAIN));
    startAlwaysRxMainChanUpdateTimer(1);
  }
  else //退出常收模式
  {
    stopAlwaysRxMainChanUpdateTimer();
    clearRecvReqEventType(EN_RECV_REQ_ALWAYS_ON_CHAN);
  }
}
#else
void rxAlwaysOnEnable(bool isEnable)
{
//空函数
  (void)isEnable;
}
#endif

static void clearRecvReqEventBitMask(uint32_t data)
{
    CORE_DECLARE_IRQ_STATE;
    CORE_ENTER_CRITICAL();      
    s_dwRecvEventBitMask &= ~data;
    CORE_EXIT_CRITICAL();     
}

uint32_t getMacRecvEventBitMask()
{
    return s_dwRecvEventBitMask;
}

void setMacRxStateEvent(MAC_RX_EVENT_TYPE_E type, bool isPass)
{
    CORE_DECLARE_IRQ_STATE;
    CORE_ENTER_CRITICAL();        
    s_dwMacRxEventTypeBitMask |= GET_DW_BIT_MASK(type);
    if(isPass)
    {
        s_dwMacRxEventValueBitMask |= GET_DW_BIT_MASK(type);
    }
    else
    {
        s_dwMacRxEventValueBitMask &= ~GET_DW_BIT_MASK(type);
    }
    CORE_EXIT_CRITICAL();        
}

static void clearMacRxStateEventType(MAC_RX_EVENT_TYPE_E type)
{
    CORE_DECLARE_IRQ_STATE;
    CORE_ENTER_CRITICAL();  
    s_dwMacRxEventTypeBitMask &= ~GET_DW_BIT_MASK(type);
    CORE_EXIT_CRITICAL(); 
}

bool getMacRxStateEventType(MAC_RX_EVENT_TYPE_E type)
{
    if(s_dwMacRxEventTypeBitMask & GET_DW_BIT_MASK(type))
    {
        return true;
    }
    return false;
}

uint8_t getMacRxStateEventValue(MAC_RX_EVENT_TYPE_E type)
{
    if(s_dwMacRxEventValueBitMask & GET_DW_BIT_MASK(type))
    {
        return 1;
    }
    return 0;
}


int setMacRecvEvent(RECV_REQ_E type, uint8_t chan)
{
    int ret = 0;
    if(type >= EN_RECV_REQ_MAX)
    {
        return -1;
    }
    
    if(CHECK_RECV_EVENT_TYPE_IS_RX_WINDOW(type) && (getMacRecvEventBitMask() & GET_DW_BIT_MASK(type)))
    {
        printf("ER%d?",type);
        return -2;
    }

    setRecvReqEventType(type);
    s_pbyRecvEventMainChan[type] = chan;
    //printf("SRE%d-%d\r\n",type,chan);
    return ret;
}


//ToDo评估 TimerCallback在中断被调用的风险setMacTransEvent，需确保线程安全性
static void waitPreambleWindowTimerCallback(struct MultiTimerHandle* timeHandle,void* pData)
{
    uint8_t byData = (uint8_t)pData;
    if(!getMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE)) //未来得及处理RF中断中的完成标志，未及时停止定时器中断 导致的异常，因此超时定时器应留足余量！
      setMacRxStateEvent(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE,false);
    //else
    //  printf("+[");
    //printf("[DBG] recv%d waitPreamblTimeout\r\n",byData); //todo
}


//需确保线程安全性，ToDo 发送超时后需将RF置为非TX态
static void waitPayloadTimerCallback(struct MultiTimerHandle* timeHandle,void* pData)
{
    uint8_t byData = (uint8_t)pData;
    if(!getMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE))
      setMacRxStateEvent(EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE,false);
    else
      printf("-]");
    //printf("[DBG] recv event%d wait payload timeout\r\n",byData); //todo
}    


bool macRxStateMachineEventCheck(STATEM_TYPE_ST* pEvent)
{
    pEvent->type = EN_MAC_RX_EVENT_TYPE_NONE;
    RX_STATE_CTRL_BLOCK_ST* pstFsmData = (RX_STATE_CTRL_BLOCK_ST*)(s_instRxStateMachine.ctrlData);
    switch(s_instRxStateMachine.currentState->handle)
    {
        case EN_RX_STATE_IDLE_PREAMBLE_FOREVER: 
            if(getMacRecvEventBitMask())
            {
                //Rx窗口接收事件
                if(getMacRecvEventBitMask() & RECV_EVENT_RX_WINDOW_BITMASK)
                {
                    pEvent->type = EN_MAC_RX_EVENT_TYPE_RECV_REQ; 
                }
                //常接收事件时，若收到有效前导码
                else if(getMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE) && (getMacRxStateEventValue(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE) == RF_PREAMBLE_DONE_IS_PASS))
                {
                    pEvent->type = EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE;
                    pEvent->data = getMacRxStateEventValue(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE);
                }
                //常接收事件时，若rx接收参数变化，fastHop关闭或 fastHop中的主信道发生变化，调换顺序0918，先处理前导码接收完成事件，再考虑因退出接收或信道切换而 重新开启接收！
                else if(pstFsmData->isFastHopOn == 0 || EN_MAC_RF_STATE_IDLE == getRfState() || (bsp_rf_get_hop_main_chan() != s_pbyRecvEventMainChan[pstFsmData->enHandlingEventType]))
                {
                    pEvent->type = EN_MAC_RX_EVENT_TYPE_RECV_REQ;
                }
                //常接收事件，RX参数未变化，未收到有效数据，即当前RF空闲
                else
                {
                  if(s_currentBackRssi == RAIL_RSSI_INVALID_DBM)
                  {
                      s_currentBackRssi = (bsp_rf_get_raw_rssi(false) >> 2);
                      printf("IR:%d\r\n",s_currentBackRssi);
                  }
                }

                //任何接收事件时，若收到有效payload
                if(getMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE) && (getMacRxStateEventValue(EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE) == RF_PAYLOAD_DONE_IS_PASS) )
                {
                    pEvent->type = EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE;
                    pEvent->data = getMacRxStateEventValue(EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE);
                }

            }     
            break; 

        case EN_RX_STATE_WAIT_PREAMBLE_TIMEOUT:
            if(getMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE))
            {
                pEvent->type = EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE;
                pEvent->data = getMacRxStateEventValue(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE);
            }            
            break;  

        case EN_RX_STATE_WAIT_SYNC_PAYLODING:
            if(getMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE))
            {
                pEvent->type = EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE;
                pEvent->data = getMacRxStateEventValue(EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE);
            }
#ifdef RX_EVENT_TYPE_RF_SYNC_DONE_ENABLED
            else if(getMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_SYNC_DONE))
            {
                pEvent->type = EN_MAC_RX_EVENT_TYPE_RF_SYNC_DONE;
                pEvent->data = getMacRxStateEventValue(EN_MAC_RX_EVENT_TYPE_RF_SYNC_DONE);                
            }
#endif
            break;    

        case EN_RX_STATE_RX_SUCCED:
            if(getMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RECV_FINISH))
            {
                pEvent->type = EN_MAC_RX_EVENT_TYPE_RECV_FINISH;
            }             
            
            break;    
        case EN_RX_STATE_RX_FAILED:
            if(getMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RECV_FINISH))
            {
                pEvent->type = EN_MAC_RX_EVENT_TYPE_RECV_FINISH;
            }            
            break;    
    }

    if(pEvent->type != EN_MAC_RX_EVENT_TYPE_NONE)
    {
        return true;
    }

    return false;
}

int macRxStateMachineRun(STATEM_TYPE_ST* pEvent) //pEvent入参
{
    STATE_MACHINE_HANDLE_RESULT_EN statMret = stateM_errArg;
    RX_STATE_CTRL_BLOCK_ST* pstFsmData = (RX_STATE_CTRL_BLOCK_ST*)(s_instRxStateMachine.ctrlData);
    int ret = -1;
    if(NULL == pEvent)
    {
        return ret;
    }

    do
    {
        if(statMret == stateM_stateNextContinue)
        {
            macRxStateMachineEventCheck(pEvent);
        }

        clearMacRxStateEventType(pEvent->type);
        if(pEvent->type != EN_MAC_RX_EVENT_TYPE_NONE) //表明有事件正需要处理
        {
            statMret = stateM_handleEvent(&s_instRxStateMachine,pEvent);
            ret = 0;
        }
        else
        {
            break;
        } 

        if(statMret == stateM_stateChanged || statMret == stateM_stateNextContinue)
        {
            if(get_mac_printf_log())
              printf("R %d-%d\r\n", pstFsmData->enHandlingEventType,s_instRxStateMachine.currentState->handle);
        }                      

    } while (statMret == stateM_stateNextContinue);
    
    return ret;
}


/************************** 状态机内相关函数指针 Guard Action ******************************************/
/*******************************************************state 0*******************************************************************/
static bool recvReqEventGuard(STATEM_STATE_MACHINE_ST* fsm, void* condition, STATEM_TYPE_ST *event)//Todo,减少循环次数
{
    uint32_t dwCondition = (uint32_t)condition;
    RX_STATE_CTRL_BLOCK_ST *pstFsmData = (RX_STATE_CTRL_BLOCK_ST *) fsm->ctrlData;
    int i;
    uint32_t temp32 = 0;

    //按优先顺序遍历接收请求，
    if(dwCondition & (getMacRecvEventBitMask()))
    {
        for(i=0;i<EN_RECV_REQ_MAX;i++)
        {
            temp32 = GET_DW_BIT_MASK(i);
            if((getMacRecvEventBitMask()) & temp32 & dwCondition)
            {
                if(temp32 & RECV_EVENT_RX_WINDOW_BITMASK)//接收窗口类事件=自清类接收事件
                {
                    clearRecvReqEventBitMask(temp32);
                    pstFsmData->enHandlingEventType = i;
                    return true;
                } 
                else // 非自清类接收事件，需判断是否有效前导码产生
                {
                    pstFsmData->enHandlingEventType = i;
                    return true;
                }       
            }
        }    
    }

    return false;

}

static bool recvPreambleForeverEventGuard(STATEM_STATE_MACHINE_ST* fsm, void* condition, STATEM_TYPE_ST *event)//Todo,减少循环次数
{
    bool ret = false;  
    if((uint8_t)condition == (uint8_t)(event->data))
    {
        ret = true;
    } 
    return ret; 
}


static bool recvReqEventActionWaitPreamble(STATEM_STATE_MACHINE_ST* fsm, STATEM_TYPE_ST *event)//
{
    RX_STATE_CTRL_BLOCK_ST *pstFsmData = (RX_STATE_CTRL_BLOCK_ST *) (fsm->ctrlData);
    uint32_t  dwTimeout = ACK_WINDOW_TIMEOUT;

    switch (pstFsmData->enHandlingEventType)
    {
        case EN_RECV_REQ_LISTEN_BACKRSSI_WINDOW: //Todo 降低开启RxWake的延时？提前开启rx 再开启定时器？，当前240418 rxWake窗口打开有近1ms的延时
            dwTimeout = LISTEN_BACKRSSI_WINDOW_TIMEOUT;
            break;
        case EN_RECV_REQ_ACK_WINDOW:
            dwTimeout = ACK_WINDOW_TIMEOUT;
            if(getMacTxStateHandlingEventType() == EN_TRANS_REQ_REGISTER)
            {
                dwTimeout = ACK_REGISTER_WINDOW_TIMEOUT;
            }
            break;
        case EN_RECV_REQ_SYNC_RXWAKE_WINDOW:
            dwTimeout = SYNC_RXWAKE_WINDOW_TIMEOUT;
            break;                    
        default:
            dwTimeout = ACK_WINDOW_TIMEOUT;
            break;
    }
    //TBD 开启之前，先清除之前可能已置位的事件
    clearMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE);
    softwareMultiTimerStart(MAC_RX_STATEMACHINE_HARD_TIMER,&waitPreambleWindowTimer,dwTimeout, waitPreambleWindowTimerCallback, (void*)(pstFsmData->enHandlingEventType) ,1);//ToDo debug

    if(pstFsmData->isFastHopOn == 1 || EN_MAC_RF_STATE_IDLE == getRfState() || (pstFsmData->byCurrentRxChan != s_pbyRecvEventMainChan[pstFsmData->enHandlingEventType]))
    {
        //开启接收，ToDo 需使用Rail库的延时 timing，前导码超时计时， 由于是发送前监听信道质量 及 发送完成后开启接收应答窗口
        //Todo，针对RxWake 引入 timing接口
        /*
         * RAIL_Status_t RAIL_SetStateTiming(RAIL_Handle_t railHandle,
                                  RAIL_StateTiming_t *timings);
///   timings.rxToTx = 192;
///   timings.txToRx = 192 - 10;
///
///   // Set other fields of timings...
///   timings.idleToRx = 100;
///   timings.idleToTx = 100;
///   timings.rxSearchTimeout = 0;
///   timings.txToRxSearchTimeout = 0;
 *
         *#define RAIL_EVENT_RX_TIMEOUT (1ULL << RAIL_EVENT_RX_TIMEOUT_SHIFT)
         * */
        startRx(s_pbyRecvEventMainChan[pstFsmData->enHandlingEventType],0);
    }

    return false;
}

static bool recvReqEventActionRestartRx(STATEM_STATE_MACHINE_ST* fsm, STATEM_TYPE_ST *event)//
{
    uint8_t ret;
    RX_STATE_CTRL_BLOCK_ST *pstFsmData = (RX_STATE_CTRL_BLOCK_ST *) (fsm->ctrlData);
    //if(pstFsmData->isFastHopOn == 0 || EN_MAC_RF_STATE_IDLE == getRfState() || (pstFsmData->byCurrentRxChan != s_pbyRecvEventMainChan[pstFsmData->enHandlingEventType]))
    //{
        startRx(s_pbyRecvEventMainChan[pstFsmData->enHandlingEventType],1);
    //}

    return false;
}

//ToDo此处可实时处理接收的payload数据报文，以及时处理报文头并 及时丢弃
static bool recvReqEventActionWaitSyncPayload(STATEM_STATE_MACHINE_ST* fsm, STATEM_TYPE_ST *event)
{
    uint32_t  dwTimeout = WAIT_ACTIVE_NORMAL_PACKET_SYNC_PAYLOAD_TIMEOUT;
    RX_STATE_CTRL_BLOCK_ST *pstFsmData = (RX_STATE_CTRL_BLOCK_ST *) (fsm->ctrlData);

    switch (pstFsmData->enHandlingEventType)
    {
        case EN_RECV_REQ_LISTEN_BACKRSSI_WINDOW:
        case EN_RECV_REQ_ACK_WINDOW:
            dwTimeout = WAIT_ACK_PACKET_SYNC_PAYLOAD_TIMEOUT;
            break;
        case EN_RECV_REQ_SYNC_RXWAKE_WINDOW:
            dwTimeout = WAIT_SYNC_BCAST_PACKET_SYNC_PAYLOAD_TIMEOUT;
            break; 

        default:
            dwTimeout = WAIT_BURST_PACKET_SYNC_PAYLOAD_TIMEOUT; //考虑一次处理的最大报文长度，接收超时，255字节负载长度+255字节前导码
            break;
    }  
      
    //TBD 是否判断重复
#ifdef RX_EVENT_TYPE_RF_SYNC_DONE_ENABLED
    clearMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_SYNC_DONE);
#endif
    clearMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE);
    softwareMultiTimerStart(MAC_RX_STATEMACHINE_HARD_TIMER,&waitPayloadTimer,dwTimeout, waitPayloadTimerCallback, (void*)(pstFsmData->enHandlingEventType) ,1);//ToDo debug
    
    return false;
}

static bool recvReqEventActionRecvSucced(STATEM_STATE_MACHINE_ST* fsm, STATEM_TYPE_ST *event)
{

  printf("/");
  setMacRxStateEvent(EN_MAC_RX_EVENT_TYPE_RECV_FINISH,false);// 同 waitSyncPayloadActionFinish函数
  return true;
}


/*******************************************************state 1*******************************************************************/
static bool waitPreambleTimeoutGuard(STATEM_STATE_MACHINE_ST* fsm, void* condition, STATEM_TYPE_ST *event)
{
    bool ret = false;  
    if((uint8_t)condition == (uint8_t)(event->data))
    {
        ret = true;
    } 
    return ret; 
}

static bool waitPreambleActionWaitSyncPayload(STATEM_STATE_MACHINE_ST* fsm, STATEM_TYPE_ST *event)
{
    if(waitPreambleWindowTimer.status != EN_MULTITIMER_STATUS_IDLE)
    {
        softwareMultiTimerStop(MAC_RX_STATEMACHINE_HARD_TIMER,&waitPreambleWindowTimer ,0);//ToDo debug
    }
    clearMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE);   

    recvReqEventActionWaitSyncPayload(fsm,event);// 进入waitSyncPayload的状态
    return false;
}

static bool waitPreambleActionFinish(STATEM_STATE_MACHINE_ST* fsm, STATEM_TYPE_ST *event)
{
    if(waitPreambleWindowTimer.status != EN_MULTITIMER_STATUS_IDLE)
    {
        softwareMultiTimerStop(MAC_RX_STATEMACHINE_HARD_TIMER,&waitPreambleWindowTimer ,0);//ToDo debug
    }
    clearMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE);       

    setMacRxStateEvent(EN_MAC_RX_EVENT_TYPE_RECV_FINISH,false);
    return true;
}


/*******************************************************state 2*******************************************************************/
static bool waitSyncPayloadGuard(STATEM_STATE_MACHINE_ST* fsm, void* condition, STATEM_TYPE_ST *event)
{
    bool ret = false;  
    if((uint8_t)condition == (uint8_t)(event->data))
    {
        ret = true;
    } 
    return ret; 
}

static bool waitSyncPayloadActionFinish(STATEM_STATE_MACHINE_ST* fsm, STATEM_TYPE_ST *event)
{
    if(waitPayloadTimer.status != EN_MULTITIMER_STATUS_IDLE)
    {
        softwareMultiTimerStop(MAC_RX_STATEMACHINE_HARD_TIMER,&waitPayloadTimer ,0);//ToDo debug
    }
    //clearMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE);  无需clear 0818修改
    setMacRxStateEvent(EN_MAC_RX_EVENT_TYPE_RECV_FINISH,false);
    return true;
}



/*******************************************************state 3..*******************************************************************/
static bool recvSuccedAction(STATEM_STATE_MACHINE_ST* fsm, STATEM_TYPE_ST *event)//结束后立即返回idle处理可能的新事件
{
    RX_STATE_CTRL_BLOCK_ST *pstFsmData = (RX_STATE_CTRL_BLOCK_ST *) (fsm->ctrlData);
    rxCompleteHandle(pstFsmData->pMacCallbackRx,fsm->currentState->handle,event);//传入接收回调指针
    clearMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE);//清除可能产生的前导码事件
    return true;
}

static bool recvFailedAction(STATEM_STATE_MACHINE_ST* fsm, STATEM_TYPE_ST *event)//Rx结束后立即返回idle处理可能的新事件
{
    RX_STATE_CTRL_BLOCK_ST *pstFsmData = (RX_STATE_CTRL_BLOCK_ST *) (fsm->ctrlData);

    if(pstFsmData->enHandlingEventType == EN_RECV_REQ_ACK_WINDOW)
    {
        setMacTxStateEvent(EN_MAC_TX_EVENT_TYPE_WAIT_ACK_DONE,false);
    }

    if (!(getMacRecvEventBitMask() & RECV_EVENT_RX_ALWAYS_ON_BITMASK))//对于常接收的角色可屏蔽该行，即 仅非常接收的角色、窗口接收的事件使用该行，ToDo ，并且修改 transition state接收成功或失败自动进入接收即可
    {
      if(getRfState() != EN_MAC_RF_STATE_TX_PAYLOADING)
      {
        //对于仅存在窗口接收事件的 子设备，也就是低功耗设备使用该行，在接收成功或失败后使RF均进入Idle态，以休眠； 而常接收状态的高功耗态设备，在接收超时后，无需手动idle
        bsp_set_rf_idle(RAIL_IDLE, false);
      }
    }

    if(pstFsmData->pMacCallbackRx != NULL)
    {
        pstFsmData->pMacCallbackRx(NULL,fsm->currentState->handle,event);
    }
    clearMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE);//清除前导码事件
    return true;
}

//接收任务优先级 低于 发送任务，不可打断发送任务，在开启接收时，需判断RF是否处于TX态；ToDo!!!若发送任务超时 需将RF芯片置为非TX态
static STATEM_STATE_ST pstRxState[EN_RX_STATE_MAX] = 
{

{
    .handle = EN_RX_STATE_IDLE_PREAMBLE_FOREVER,
    .numTransitions = 4,
    .transitions = (STATEM_TRANSITION_ST[])
    {     
        {EN_MAC_RX_EVENT_TYPE_RECV_REQ,RECV_EVENT_RX_WINDOW_BITMASK,recvReqEventGuard,recvReqEventActionWaitPreamble,&(pstRxState[EN_RX_STATE_WAIT_PREAMBLE_TIMEOUT])}, 
        {EN_MAC_RX_EVENT_TYPE_RECV_REQ,~RECV_EVENT_RX_WINDOW_BITMASK,recvReqEventGuard,recvReqEventActionRestartRx,&(pstRxState[EN_RX_STATE_IDLE_PREAMBLE_FOREVER])}, 
        {EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE,RF_PREAMBLE_DONE_IS_PASS,recvPreambleForeverEventGuard,recvReqEventActionWaitSyncPayload,&(pstRxState[EN_RX_STATE_WAIT_SYNC_PAYLODING])},
        //ToDo 新增 payload done事件处理，异常处理，概率较低
        {EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE,RF_PAYLOAD_DONE_IS_PASS,NULL,recvReqEventActionRecvSucced,&(pstRxState[EN_RX_STATE_RX_SUCCED])}
    }
},


{
    .handle = EN_RX_STATE_WAIT_PREAMBLE_TIMEOUT,
    .numTransitions = 2,
    .transitions = (STATEM_TRANSITION_ST[])
    {
        {EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE,RF_PREAMBLE_DONE_IS_PASS,waitPreambleTimeoutGuard,waitPreambleActionWaitSyncPayload,&(pstRxState[EN_RX_STATE_WAIT_SYNC_PAYLODING])},
        {EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE,!RF_PREAMBLE_DONE_IS_PASS,waitPreambleTimeoutGuard,waitPreambleActionFinish,&(pstRxState[EN_RX_STATE_RX_FAILED])},
    }
},

{
    .handle = EN_RX_STATE_WAIT_SYNC_PAYLODING,//ToDo，报文接收过程中，可实时读取缓存区的报文头部 进行滚动码和地址的校验 以及时停止接收非目的地报文；
#ifdef RX_EVENT_TYPE_RF_SYNC_DONE_ENABLED
    .numTransitions = 3,
#else
    .numTransitions = 2,
#endif
    .transitions = (STATEM_TRANSITION_ST[])
    {
#ifdef RX_EVENT_TYPE_RF_SYNC_DONE_ENABLED
        {EN_MAC_RX_EVENT_TYPE_RF_SYNC_DONE,!RF_SYNC_DONE_IS_PASS,waitSyncPayloadGuard,waitSyncPayloadActionFinish,&(pstRxState[EN_RX_STATE_RX_FAILED])}, 
#endif
        {EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE,RF_PAYLOAD_DONE_IS_PASS,waitSyncPayloadGuard,waitSyncPayloadActionFinish,&(pstRxState[EN_RX_STATE_RX_SUCCED])},
        {EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE,!RF_PAYLOAD_DONE_IS_PASS,waitSyncPayloadGuard,waitSyncPayloadActionFinish,&(pstRxState[EN_RX_STATE_RX_FAILED])},        
    }
},

{
    .handle = EN_RX_STATE_RX_SUCCED, //报文接收成功
    .numTransitions = 1,
    .transitions = (STATEM_TRANSITION_ST[])
    {
        {EN_MAC_RX_EVENT_TYPE_RECV_FINISH,NULL,NULL,recvSuccedAction,&(pstRxState[EN_RX_STATE_IDLE_PREAMBLE_FOREVER])},
    }
},

{
    .handle = EN_RX_STATE_RX_FAILED,
    .numTransitions = 1,
    .transitions = (STATEM_TRANSITION_ST[])
    {
        {EN_MAC_RX_EVENT_TYPE_RECV_FINISH,NULL,NULL,recvFailedAction,&(pstRxState[EN_RX_STATE_IDLE_PREAMBLE_FOREVER])},
    }
}

};


void macRxStateMachineInit(PFUNC_RX_CALLBACK pArrayFun)
{
    uint8_t i;
    if(pArrayFun != NULL)
    {
        s_stRxCtrlBlock.pMacCallbackRx = pArrayFun;
    }

    s_dwRecvEventBitMask = 0x00000000;
    s_stRxCtrlBlock.byCurrentRxChan = RF_CHAN_RESYNC_DEFAULT_NUMBER;
    s_stRxCtrlBlock.isFastHopOn = 0;
    s_stRxCtrlBlock.enHandlingEventType = EN_RECV_REQ_NONE;
    stateM_init(&s_instRxStateMachine ,&pstRxState[EN_RX_STATE_IDLE_PREAMBLE_FOREVER] ,&pstRxState[EN_RX_STATE_RX_FAILED],&s_stRxCtrlBlock);
}

bool isRxStateRfIdle()
{
  if(s_instRxStateMachine.currentState->handle == EN_RX_STATE_IDLE_PREAMBLE_FOREVER && (!(getMacRecvEventBitMask() & RECV_EVENT_RX_ALWAYS_ON_BITMASK)))
  {
    return true;
  }
  return false;
}
